﻿using jiuyuan.数据.共享类;
using jiuyuan.数据.基础数据类;
using jiuyuan.管理器;
using System.Text.Json;

namespace jiuyuan.服务;

// 效果触发时机枚举
public enum 效果触发时机
{
    立即触发,      // 使用时立即触发
    战斗开始,      // 战斗开始时触发
    回合开始,      // 回合开始时触发
    攻击时,        // 攻击时触发
    受击时,        // 受到攻击时触发
    装备时,        // 装备时触发
    卸下时,        // 卸下时触发
    常驻效果       // 持续生效
}

// 技能效果基类
public abstract class 技能效果
{
    public Guid Id { get; set; } = Guid.CreateVersion7();
    public string 效果名称 { get; set; } = string.Empty;
    public string 效果描述 { get; set; } = string.Empty;
    public 效果触发时机 触发时机 { get; set; }
    public float 触发概率 { get; set; } = 1.0f;
    public Dictionary<string, object> 参数 { get; set; } = [];
    public int 持续回合数 { get; set; } = 0; // 添加持续回合数属性

    // 用于数据库存储的参数JSON字符串
    public string 参数Json 
    { 
        get => JsonSerializer.Serialize(参数);
        set => 参数 = string.IsNullOrEmpty(value) ? [] : JsonSerializer.Deserialize<Dictionary<string, object>>(value) ?? [];
    }

    // 抽象属性，子类必须实现
    public abstract string 效果类型名称 { get; }

    /// <summary>
    /// 应用效果
    /// </summary>
    public abstract void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器);

    /// <summary>
    /// 获取效果描述
    /// </summary>
    public virtual string 获取描述()
    {
        return 效果描述;
    }

    /// <summary>
    /// 深拷贝
    /// </summary>
    public virtual 技能效果 深拷贝()
    {
        var 新效果 = (技能效果)MemberwiseClone();
        新效果.参数 = new Dictionary<string, object>(参数);
        return 新效果;
    }
}

// 伤害效果
public class 伤害效果 : 技能效果
{
    public override string 效果类型名称 => "伤害效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        var 伤害值 = 参数.TryGetValue("基础伤害", out var 伤害) ? Convert.ToInt32(伤害) : 0;
        var 元素类型 = 参数.TryGetValue("元素类型", out var 元素) ? (元素属性类型)Enum.Parse(typeof(元素属性类型), 元素.ToString()!) : 元素属性类型.无;

        foreach (var 目标 in 目标列表)
        {
            // 计算实际伤害（这里简化处理）
            var 实际伤害 = 伤害值;

            // 应用伤害
            目标.当前生命值 = Math.Max(0, 目标.当前生命值 - 实际伤害);

            // 记录日志
            Console.WriteLine($"{施法者.名称} 对 {目标.名称} 造成了 {实际伤害} 点伤害");
        }
    }

    public override string 获取描述()
    {
        var 伤害值 = 参数.TryGetValue("基础伤害", out var 伤害) ? Convert.ToInt32(伤害) : 0;
        return $"造成 {伤害值} 点伤害";
    }
}

// 治疗效果
public class 治疗效果 : 技能效果
{
    public override string 效果类型名称 => "治疗效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        var 治疗值 = 参数.TryGetValue("基础治疗", out var 治疗) ? Convert.ToInt32(治疗) : 0;

        foreach (var 目标 in 目标列表)
        {
            // 计算实际治疗（这里简化处理）
            var 实际治疗 = 治疗值;

            // 应用治疗
            目标.当前生命值 = Math.Min(目标.当前属性.生命值, 目标.当前生命值 + 实际治疗);

            // 记录日志
            Console.WriteLine($"{施法者.名称} 为 {目标.名称} 恢复了 {实际治疗} 点生命值");
        }
    }

    public override string 获取描述()
    {
        var 治疗值 = 参数.TryGetValue("基础治疗", out var 治疗) ? Convert.ToInt32(治疗) : 0;
        return $"恢复 {治疗值} 点生命值";
    }
}

// 增益效果
public class 增益效果 : 技能效果
{
    public 属性配置 增益属性 { get; set; } = new 属性配置(); // 添加增益属性字段
    
    public override string 效果类型名称 => "增益效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        var 持续回合 = 持续回合数 > 0 ? 持续回合数 : (参数.TryGetValue("持续回合", out var 回合) ? Convert.ToInt32(回合) : 1);

        foreach (var 目标 in 目标列表)
        {
            // 创建持续效果实例
            var 持续效果 = new 持续效果
            {
                Id = Guid.CreateVersion7(),
                效果名称 = 效果名称,
                剩余回合数 = 持续回合,
                基础效果 = this,
                施加者 = 施法者,
                目标 = 目标
            };

            // 添加到目标的持续效果列表
            目标.持续效果列表.Add(持续效果);

            // 立即应用属性加成
            目标.当前属性 = 属性配置.合并属性(目标.当前属性, 增益属性);

            // 记录日志
            Console.WriteLine($"{施法者.名称} 为 {目标.名称} 施加了 {效果名称} 效果，持续 {持续回合} 回合");
        }
    }

    public override string 获取描述()
    {
        var 描述 = "获得属性加成：";
        if (增益属性.生命值 > 0) 描述 += $"生命值+{增益属性.生命值} ";
        if (增益属性.魔法值 > 0) 描述 += $"魔法值+{增益属性.魔法值} ";
        if (增益属性.物理攻击 > 0) 描述 += $"物理攻击+{增益属性.物理攻击} ";
        if (增益属性.物理防御 > 0) 描述 += $"物理防御+{增益属性.物理防御} ";
        return 描述.Trim();
    }
}

// 持续伤害效果
public class 持续伤害效果 : 技能效果
{
    public override string 效果类型名称 => "持续伤害效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        var 持续回合 = 持续回合数 > 0 ? 持续回合数 : (参数.TryGetValue("持续回合", out var 回合) ? Convert.ToInt32(回合) : 3);
        var 每回合伤害 = 参数.TryGetValue("每回合伤害", out var 伤害) ? Convert.ToInt32(伤害) : 10;

        foreach (var 目标 in 目标列表)
        {
            // 创建持续效果实例
            var 持续效果 = new 持续效果
            {
                Id = Guid.CreateVersion7(),
                效果名称 = 效果名称,
                剩余回合数 = 持续回合,
                基础效果 = this,
                施加者 = 施法者,
                目标 = 目标
            };

            // 添加到目标的持续效果列表
            目标.持续效果列表.Add(持续效果);

            // 记录日志
            Console.WriteLine($"{施法者.名称} 为 {目标.名称} 施加了 {效果名称} 效果，持续 {持续回合} 回合");
        }
    }

    public override string 获取描述()
    {
        var 每回合伤害 = 参数.TryGetValue("每回合伤害", out var 伤害) ? Convert.ToInt32(伤害) : 10;
        var 持续回合 = 持续回合数 > 0 ? 持续回合数 : (参数.TryGetValue("持续回合", out var 回合) ? Convert.ToInt32(回合) : 3);
        return $"每回合造成 {每回合伤害} 点持续伤害，持续 {持续回合} 回合";
    }
}

// 属性加成效果（用于装备）
public class 属性加成效果 : 技能效果
{
    public override string 效果类型名称 => "属性加成效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        // 属性加成效果在装备时由装备管理器处理
        // 这里不需要额外处理
    }

    public override string 获取描述()
    {
        var 描述 = "属性加成：";
        if (参数.TryGetValue("生命值", out var hp)) 描述 += $"生命值+{hp} ";
        if (参数.TryGetValue("魔法值", out var mp)) 描述 += $"魔法值+{mp} ";
        if (参数.TryGetValue("物理攻击", out var atk)) 描述 += $"物理攻击+{atk} ";
        if (参数.TryGetValue("物理防御", out var def)) 描述 += $"物理防御+{def} ";
        return 描述.Trim();
    }
}

// 触发技能效果
public class 触发技能效果 : 技能效果
{
    public override string 效果类型名称 => "触发技能";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        // 触发技能效果的具体实现
        // 这里可以添加触发其他技能的逻辑
    }

    public override string 获取描述()
    {
        return "触发其他技能效果";
    }
}

// 状态效果
public class 状态效果 : 技能效果
{
    public override string 效果类型名称 => "状态效果";

    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        // 状态效果的具体实现
        // 这里可以添加状态改变的逻辑
    }

    public override string 获取描述()
    {
        return "改变目标状态";
    }
}

// 动态技能效果基类
public abstract class 动态技能效果 : 技能效果
{
    public override string 效果类型名称 => "动态技能效果";
    
    // 动态效果可以包含更复杂的逻辑
    public abstract void 应用动态效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器);
    
    public override void 应用效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        应用动态效果(施法者, 目标列表, 来源, 战斗管理器);
    }
}

// 动态伤害效果
public class 动态伤害效果 : 动态技能效果
{
    public override string 效果类型名称 => "动态伤害效果";
    
    public override void 应用动态效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        // 动态伤害效果的具体实现
        // 可以根据施法者属性、目标状态等动态计算伤害
    }
    
    public override string 获取描述()
    {
        return "根据条件动态计算伤害";
    }
}

// 动态治疗效果
public class 动态治疗效果 : 动态技能效果
{
    public override string 效果类型名称 => "动态治疗效果";
    
    public override void 应用动态效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        // 动态治疗效果的具体实现
        // 可以根据施法者属性、目标状态等动态计算治疗量
    }
    
    public override string 获取描述()
    {
        return "根据条件动态计算治疗量";
    }
}

// 动态属性增益效果
public class 动态属性增益效果 : 动态技能效果
{
    public override string 效果类型名称 => "动态属性增益效果";
    
    public override void 应用动态效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        // 动态属性增益效果的具体实现
        // 可以根据条件动态计算属性加成
    }
    
    public override string 获取描述()
    {
        return "根据条件动态计算属性加成";
    }
}

// 动态速度减益效果
public class 动态速度减益效果 : 动态技能效果
{
    public override string 效果类型名称 => "动态速度减益效果";
    
    public override void 应用动态效果(战斗单位 施法者, List<战斗单位> 目标列表, object? 来源, 战斗管理器? 战斗管理器)
    {
        // 动态速度减益效果的具体实现
        // 可以根据条件动态计算速度减益
    }
    
    public override string 获取描述()
    {
        return "根据条件动态计算速度减益";
    }
}
